1. /* scfcatan.cpp by K.Tsuru */
  2. // function ID = 9116 since ver 2.18
  3. /****************************************************
  4. SComplex class
  5. It returns arctan(z). z = x+iy
  6. Catan(z) = (i/2) * Clog{(i + z)/(i - z)}.
  7. Catan(iy) = i*Atanh(y)
  8. Let z = x [+|-] i*y
  9. arctan(z) = arctan(x [+|-] i*y) ([+|-]y >= 0)
  10. 1 2x i 2y
  11. =--- arctan ----------- [+|-] ---artanh-----------
  12. 2 1-x^2 -y^2 2 1+x^2+y^2
  13. *****************************************************/
  14. #ifndef SN_H
  15. #include "sn.h"
  16. #endif
  17. #define CatanIZMethod 1 // 25.0sec ...fastest
  18. #define CatanXYMethod 0 // 25.9sec
  19. // WolframMethod // 36.9
  20. static const SComplex I_2(0.0, 0.5); // i/2
  21. SComplex Catan(const SComplex& z){
  22. if(z == 0.0) return 0.0;
  23. if(Re(z) == 0.0){ // pure imaginary z = iy
  24. if(Dabs(Im(z)) >= 1.0) z.Real().SetError(z.Real().DOMAIN_ERR, "Catan z = iy(|y| > 1.0))", 9116);
  25. return SComplex( 0.0, Atanh(Im(z)) ); // i*atanh(y)
  26. }
  27. SComplex r;
  28. #if CatanIZMethod // faster than below
  29. SComplex p = (IU + z)/(IU - z);
  30. r = I_2 * Clog(p);
  31. #elif CatanXYMethod
  32. SDouble x(Re(z)), y(Im(z)), zsq = x*x+y*y, d1 = zsq - 1.0;
  33. if(d1.IsHidden()) r = SComplex(MPi4(), Atanh(Sin(x))/2); // |z|=1
  34. else {
  35. SDouble p, q, d;
  36. p = 2*x; d = 1-zsq; q = Atan2(p, d); // instead of Atan(p/d) you must use Atan2(x, y)
  37. x = DsDiv(q, 2);
  38. p = 2*y/(1+zsq); q = Atanh(p); y = DsDiv(q, 2);
  39. r = SComplex(x, y);
  40. }
  41. #else
  42. // WolframMethod
  43. // arctan z = (i/2)[ln(1-iz)-ln(1+iz)]
  44. // 1-iz = 1-i(x+iy) = 1+y -ix, 1+iz = 1-y+ix
  45. SDouble x = Re(z), y = Im(z);
  46. SComplex p(1+y, -x), q(1-y,x);
  47. r = Clog(p) - Clog(q);
  48. r = I_2 * r;
  49. #endif
  50. return r;
  51. }

scfcatan.cpp : last modifiled at 2015/10/23 15:47:11(1,715 bytes)
created at 2017/10/06 15:21:28
The creation time of this html file is 2017/10/06 15:27:08 (Fri Oct 06 15:27:08 2017).